package com.k.kpp.web.controller;

import com.k.kc.util.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author k
 */
@Controller
public class ThreadController {
    @Autowired
    private ExecutorService executorService;

    /**
     * task1:1000ms task2:2000ms task3:3000ms  task4:4000ms
     * 多线程并发任务4个任务总用时 MAX(taskTime)=4s
     *
     * 单线程4个任务总用时：SUM(taskTime)=10s
     *
     * @return result
     */
    @RequestMapping("/thread")
    @ResponseBody
    public List<String> thread(){
        System.out.println(DateUtils.now());
        int taskCount = 4;
        List<Future<String>> futureList = new ArrayList<>();
        // 1.req
        for(int i=0;i<taskCount;i++){
            Future<String> future = executorService.submit(new Callable<String>() {
                private int itm;
                Callable setItm(int itm) {
                    this.itm = itm;
                    return this;
                }
                @Override
                public String call() throws Exception {
                    Thread.sleep(1000*(itm+1));
                    return "task"+(itm+1);
                }
            }.setItm(i));
            futureList.add(future);
        }

        // 2.res
        List<String> result = new ArrayList<>();
        for(int j=0;j<taskCount;j++){
            Future<String> future = futureList.get(j);
            if(future != null){
                try {
                    String res = future.get();
                    result.add(res);
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println(DateUtils.now()+":multiple thread result:"+result);
        return result;
    }

    /**
     * test thread two thread2?count=4
     * @return string
     */
    @RequestMapping("/thread2")
    @ResponseBody
    public List<String> thread2(int count){
        long startTime = System.currentTimeMillis();
        List<String> result = new ArrayList<>();
        int threadCount = count;
        int taskCount = 4;
        ExecutorService pool = Executors.newFixedThreadPool(threadCount);
        List<Future<String>> futureList = new ArrayList<>();
        for(int i=0;i<taskCount;i++){
            Future<String> future = pool.submit(new Callable<String>() {
                private int taskInt;
                Callable setTaskInt(int taskInt){
                    this.taskInt = taskInt+1;
                    return this;
                }
                @Override
                public String call() throws Exception {
                    Thread.sleep(1000*taskInt);
                    System.out.println(DateUtils.nowMs()+" task"+taskInt);
                    return DateUtils.nowMs()+"-"+Thread.currentThread()+":task"+taskInt;
                }
            }.setTaskInt(i));
            futureList.add(future);
        }

        for(Future<String> f:futureList){
            try {
                String res = f.get();
                result.add(res);
            } catch (InterruptedException |  ExecutionException e) {
                e.printStackTrace();
            }
        }
        long endTime = System.currentTimeMillis();
        long timeC = endTime - startTime;
        System.out.println("用时："+timeC);

        return result;
    }
}
